package com.edushare.common.backup;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import nu.xom.Comment;
import nu.xom.Document;
import nu.xom.Element;
import nu.xom.Serializer;

import com.edushare.common.constants.ApplicationConstants;
import com.edushare.common.constants.ConfigPropertyName;
import com.edushare.common.exceptions.EduShareRuntimeException;
import com.edushare.common.global.SystemGlobals;
import com.edushare.common.util.DateTimeUtil;
import com.edushare.common.util.SystemUtils;
import com.edushare.common.vo.SystemBackup;

/**
 * <pre>
 * &lt;?xml version="1.0"?&gt;
 * &lt;edushare-bkp&gt;
 * 	&lt;specs&gt;
 * 		&lt;title&gt;&lt;/title&gt;
 * 		&lt;bkp-date&gt;&lt;/bkp-date&gt;
 * 		&lt;bkp-type&gt;&lt;/bkp-type&gt;
 * 		&lt;version&gt;&lt;/version&gt;
 * 		&lt;creator&gt;&lt;/creator&gt;
 * 	&lt;/specs&gt;
 * 	
 * 	&lt;files&gt;
 * 		&lt;db-files&gt;
 * 			&lt;file&gt;&lt;/file&gt;
 * 			&lt;file&gt;&lt;/file&gt;
 * 		&lt;/db-files&gt;
 * 		&lt;media-files&gt;
 * 			&lt;file&gt;&lt;/file&gt;
 * 			&lt;file&gt;&lt;/file&gt;
 * 		&lt;/media-files&gt;
 * 	&lt;/files&gt;	
 * &lt;/edushare-bkp&gt;
 * </pre>
 * @author naishe
 *
 */
public class BackupConfigFileProcessor {

	
	//List of elements
	public static final String ROOT 					= "edushare-bkp";
	
	public static final String SPECS 					= "specs";
	public static final String BACKUP_TITLE 			= "title";
	public static final String BACKUP_DATE 				= "bkp-date";
	public static final String BACKUP_TYPE 				= "bkp-type";
	public static final String VERSION 					= "version";
	public static final String CREATOR 					= "creator";
	
	public static final String BACKUP_FILES				= "files";
	public static final String DATABASE_BACKUP_FILES 	= "db-files";
	public static final String MEDIA_BACKUP_FILES 		= "media-files";
	public static final String BACKUP_FILE 				= "file";
	
	
	/** <p>
	 * Creates and saves the configuration file for the backup in given back-up folder.
	 * </p>
	 * @param backup directory
	 * @param craeting user
	 * @throws IOException 
	 */
	public static void createBackupConfigFile(SystemBackup bkp) throws IOException {
		
		Element root = new Element(ROOT);
		
		//comment
		String nfo = "***** DO NOT EDIT OR RENAME THIS FILE *****";
		String nfo1 = "SYSTEM BACKUP METADATA FILE FOR "
			+ ApplicationConstants.APPLICATION_NAME+" VERSION " 
			+ SystemGlobals.getInstance().getConfigProperty(ConfigPropertyName.SYSTEM_CURRENT_VERSION);
		String nfo2 = "CREATED ON: " + DateTimeUtil.formatTimestamp(bkp.getCreationTimestamp());
		String nfo3 = "CREATED BY: " + bkp.getCreator().getCompleteUserName();
		root.appendChild(new Comment(nfo));
		root.appendChild(new Comment(nfo1));
		root.appendChild(new Comment(nfo2));
		root.appendChild(new Comment(nfo3));
		
		//Specs
		Element specs = new Element(SPECS);
		root.appendChild(specs);
		
		Element title = new Element(BACKUP_TITLE);
		title.appendChild(bkp.getBackupTitle());
		specs.appendChild(title);
				
		Element bkpDate = new Element(BACKUP_DATE);
		bkpDate.appendChild(bkp.getCreationTimestamp().getTime()+"");
		specs.appendChild(bkpDate);
		
		Element bkpType = new Element(BACKUP_TYPE);
		bkpType.appendChild(bkp.getBackupType().toString());
		specs.appendChild(bkpType);
		
		Element version = new Element(VERSION);
		version.appendChild(SystemGlobals.getInstance().getConfigProperty(ConfigPropertyName.SYSTEM_CURRENT_VERSION));
		specs.appendChild(version);
		
		Element creator = new Element(CREATOR);
		creator.appendChild(bkp.getCreator().getCompleteUserName() + " (" + bkp.getCreator().getUserName()+")");
		specs.appendChild(creator);
		
		//Files
		Element files = new Element(BACKUP_FILES);
		root.appendChild(files);
		
		Element dbFiles = new Element(DATABASE_BACKUP_FILES);
		files.appendChild(dbFiles);
		
		for(String dbfile: getFiles(bkp, SystemBackup.DB_BKP_FILE_PREFIX)){
			Element file = new Element(BACKUP_FILE);
			file.appendChild(dbfile);
			dbFiles.appendChild(file);
		}
		
		Element mediaFiles = new Element(MEDIA_BACKUP_FILES);
		files.appendChild(mediaFiles);
		
		for(String mediafile: getFiles(bkp, SystemBackup.MEDIA_BKP_FILE_PREFIX)){
			Element file = new Element(BACKUP_FILE);
			file.appendChild(mediafile);
			mediaFiles.appendChild(file);
		}
		
		writeTotheFile(root, bkp);
		
	}


	private static List<String> getFiles(SystemBackup bkp, String filePrefix) {
		File dir = new File(SystemUtils.getAbsolutePathFromRelative(bkp.getDirectoryPath()));
		if(dir==null||!dir.exists())
			throw new EduShareRuntimeException("The backup directory empty or DNE.");
		
		List<String> files = new ArrayList<String>();
		for(String s: dir.list()){
			if(s.startsWith(filePrefix))
				files.add(s);
		}
		
		return files;
	}
	
	private static void writeTotheFile(Element rootElement, SystemBackup bkp) throws IOException {
		
		Document doc = new Document(rootElement);
		File f = new File(new File(SystemUtils.getAbsolutePathFromRelative(bkp.getDirectoryPath())),
							SystemBackup.CONFIG_FILE_NAME);
		
		FileOutputStream outStream;
		Serializer serializer = new Serializer(outStream = new FileOutputStream(f));
		serializer.setIndent(4);
		serializer.setMaxLength(80);
		serializer.write(doc);
		if(outStream!=null)
			outStream.close();
	}
	
}
